﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Server.Network
{
    /// <summary>
    /// 비동기 서버를 제공합니다.
    /// </summary>
    public class AsyncServer
    {
        /// <summary>
        /// 버퍼사이즈를 가져옵니다.
        /// </summary>
        const int BUFFER_SIZE = 1024;

        /// <summary>
        /// 비동기 서버가 데이터를 Receive 받으면 발생하는 이벤트를 제공합니다.
        /// </summary>
        public event AsyncServerRecieveDelegate AsyncServerRecieveEvent;

        /// <summary>
        /// 비동기 서버를 시작합니다.
        /// </summary>
        /// <param name="asyncServerRecieveEvent">데이터를 Receive 받으면 발생하는 이벤트</param>
        public void RunProc(AsyncServerRecieveDelegate asyncServerRecieveEvent)
        {
            AsyncServerRecieveEvent += asyncServerRecieveEvent;

            Socket listen_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listen_sock.Bind(new IPEndPoint(IPAddress.Any, 8192));
            listen_sock.Listen(10);

            while (true)
            {
                Socket client_sock = listen_sock.Accept();
                SocketAsyncEventArgs se = new SocketAsyncEventArgs();
                se.AcceptSocket = client_sock;
                se.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);
                se.Completed += new EventHandler<SocketAsyncEventArgs>(SocketIOCompleteEvent);
                client_sock.ReceiveAsync(se);
            }
        }

        /// <summary>
        /// IOCompleteEvent를 정의합니다.
        /// </summary>
        private void SocketIOCompleteEvent(object sender, SocketAsyncEventArgs se)
        {
            switch (se.LastOperation)
            {
                case SocketAsyncOperation.Receive:
                    //byte[] sendByte = AsyncServerRecieveEvent(se.Buffer);
                    byte[] sendByte = AsyncServerRecieveEvent(se);
                    se.AcceptSocket.Send(sendByte);
                    break;
            }
        }
    }
}
